# -*- coding: utf-8 -*-

from django.views.decorators.http import require_POST

from common.mch import handler as mch_handler
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.api import check_params
from common.utils.decorator import response_wrapper
from common.utils.geo import get_city
from common.withdraw import db as withdraw_db
from common.withdraw import handler as withdraw_handler
from common.withdraw.model import WITHDRAW_ORDER_STATUS
from common.bankcard.model import BANK_DCT

_LOGGER = track_logging.getLogger(__name__)


@require_POST
@response_wrapper
def create(request):
    """
    提现订单创建
    PARAMS:
      sdk_version: sdk version code
      mch_id: 商户号
      out_trade_no: 商户订单号
      amount: 总金额
      notify_url: 异步通知接口
      sign: 签名
      extra: 附加信息，回调时返回
      bank: 银行名称
      bank_subbranch: 支行名称
      bankcard_no: 银行卡号
      bandcard_owner: 银行卡名称
    """
    params = request.POST.dict()
    _LOGGER.info('create withdraw request: %s', params)
    check_params(params,
                 ['sdk_version', 'mch_id', 'out_trade_no', 'body', 'pay_type', 'user_id',
                  'pay_account_bank', 'pay_account_bank_subbranch', 'pay_account_num',
                  'pay_account_username', 'amount', 'notify_url', 'sign', 'client_ip'],
                 param_type_dct={
                     'mch_id': basestring,
                     'out_trade_no': basestring,
                 }
                 )
    sign = params.pop('sign')    

    calculated_sign = mch_handler.generate_sign(params['mch_id'], params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')

    if float(params['amount']) > 50000:
        _LOGGER.warning('amount not valid: %s' % params['amount'])
        raise err.ParamError('amount invalid')

    if params['pay_account_bank'] is None:
        raise err.ParamError('pay_account_bank is None')

    params['region'] = get_city(params['client_ip']) or params['region']
    params['pay_account_num'] = params['pay_account_num'].replace(' ', '')

    # 判断out_trade_no是否存在
    exist_order = withdraw_db.get_order_by_out_trade_no(
        int(params['mch_id']), params['out_trade_no']
    )
    if exist_order:
        raise err.ParamError('out_trade_no exists')

    withdraw_order = withdraw_db.create_order(params)

    # 检查提现信息是否合法
    order_valid = withdraw_handler.check_order(withdraw_order)
    if not order_valid:
        _LOGGER.info('withdraw order %s not_valid', withdraw_order.id)
        return {
            'order_id': withdraw_order.id,
            'order_status': WITHDRAW_ORDER_STATUS.REJECTED,
            'reason': withdraw_order.detail
        }

    # 判断是否需要并提交第三方
    try:
        _LOGGER.info('process_withdraw: %s', withdraw_order.id)
        withdraw_handler.process_withdraw(withdraw_order)
        _LOGGER.info('process_withdraw %s , status: %s', withdraw_order.id, withdraw_order.status)
    except Exception as e:
        _LOGGER.info('process_withdraw %s process with error: %s', withdraw_order.id, str(e))

    return {
        'order_id': withdraw_order.id,
        'order_status': WITHDRAW_ORDER_STATUS.WAIT,
        'reason': ''
    }


@require_POST
@response_wrapper
def query(request):
    """
    提现订单状态查询
    """
    params = request.POST.dict()
    check_params(
        params,
        ['mch_id', 'out_trade_no', 'sign'],
        param_type_dct={
            'mch_id': basestring,
            'out_trade_no': basestring,
        }
    )

    sign = params.pop('sign')
    calculated_sign = mch_handler.generate_sign(params['mch_id'], params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')

    order = withdraw_db.get_order_by_out_trade_no(params['mch_id'], params['out_trade_no'])
    if not order:
        raise err.ParamError('out_trade_no %s not exist' % params['out_trade_no'])
    else:
        return {
            "order_id": order.id,
            "order_status": order.status,
            "out_trade_no": params['out_trade_no'],
        }
